package com.authine.cloudpivot.controller;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.json.JSONObject;
import com.alibaba.fastjson.JSON;
import com.authine.cloudpivot.domain.IronTowerDto;
import com.authine.cloudpivot.domain.ItData;
import com.authine.cloudpivot.domain.MessageParam;
import com.authine.cloudpivot.engine.api.facade.BizObjectFacade;
import com.authine.cloudpivot.engine.api.facade.OrganizationFacade;
import com.authine.cloudpivot.engine.api.facade.WorkflowInstanceFacade;
import com.authine.cloudpivot.engine.api.model.organization.UserModel;
import com.authine.cloudpivot.engine.api.model.runtime.AttachmentModel;
import com.authine.cloudpivot.engine.api.model.runtime.BizObjectModel;
import com.authine.cloudpivot.engine.domain.organization.Department;
import com.authine.cloudpivot.engine.enums.status.WorkflowInstanceStatus;
import com.authine.cloudpivot.engine.enums.type.DefaultPropertyType;
import com.authine.cloudpivot.engine.open.OpenEngineFactory;
import com.authine.cloudpivot.engine.open.service.OpenEngine;
import com.authine.cloudpivot.engine.service.impl.runtime.BizAttachmentServiceImpl;
import com.authine.cloudpivot.engine.service.organization.DepartmentService;
import com.authine.cloudpivot.foundation.orm.api.dml.BizObjectRepository;
import com.authine.cloudpivot.foundation.orm.api.dml.JPANativeQuery;
import com.authine.cloudpivot.service.CjfxOpenApiService2;
import com.authine.cloudpivot.util.CoordtransformUtils;
import com.authine.cloudpivot.util.PolygonUtil;
import com.authine.cloudpivot.util.Result;
import com.authine.cloudpivot.web.api.controller.base.BaseController;
import com.authine.cloudpivot.web.api.controller.common.OSSController;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.awt.geom.Point2D;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.time.LocalTime;
import java.util.*;

@RestController
@RequestMapping("/api/alarm")
@Slf4j
public class IronTowerController extends BaseController {

    private static final String SCHMEA_CODE = "italarm";  //test


    private static final String USERID = "6b42ebe5236d4ecd84332710e5285fd0";

    private static final String DEPID = "ff8080819431dab7019444d8f9e10f01";

    @Autowired
    OSSController oSSController;

    @Autowired
    BizObjectRepository bizObjectRepository;

    @Autowired
    BizObjectFacade bizObjectFacade;


    @Autowired
    BizAttachmentServiceImpl bizAttachmentService;

    @Autowired
    private OrganizationFacade organizationFacade;

    @Autowired
    private CjfxOpenApiService2 cjfxOpenApiService;
    @Autowired
    private DepartmentService departmentService;
    @Autowired
    private QueryReportSqlController queryReportSqlController;
    @Autowired
    private WorkflowInstanceFacade workflowInstanceFacade;
    @Autowired
    private JPANativeQuery jpaNativeQuery;



    @PostMapping("/receive")
    public Result receiveData(@RequestBody IronTowerDto ironTowerDto){
        try {
            BizObjectModel bizObjectModel = makeUpData(ironTowerDto);
            String userId = bizObjectModel.getString(DefaultPropertyType.CREATER.getCode());
            String deptId = bizObjectModel.getString(DefaultPropertyType.CREATED_DEPT_ID.getCode());
            if (StringUtils.isBlank(userId) || StringUtils.isBlank(deptId)) {
                userId = USERID;
                deptId = DEPID;
            }
            bizObjectModel.setSequenceStatus(WorkflowInstanceStatus.COMPLETED.toString());
            bizObjectFacade.saveBizObjectModel(userId,bizObjectModel,null);
            return Result.ok();
        } catch (Exception e) {
            log.error("sync Alarm data error,,msg:{}", e);
        }
        return Result.ok();
    }

    private BizObjectModel makeUpData(IronTowerDto ironTowerDto) {
        log.info("告警信息:{}",JSON.toJSONString(ironTowerDto));
        String departmentName = null;
        ItData itData = ironTowerDto.getData();
        Map<String, Object> data = BeanUtil.beanToMap(itData);
        data.put("eventId",ironTowerDto.getEventId());
        String longitude = itData.getEventLongitude();
        String latitudes = itData.getEventLatitude();
        String location = longitude + "," + latitudes;
        JSONObject convert = cjfxOpenApiService.convert(location);
        JSONObject address = cjfxOpenApiService.getAddress(convert.getStr("locations"));
        JSONObject regeocode = address.getJSONObject("regeocode");
        String formattedAddress = regeocode.getStr("formatted_address");
        // 填充地址信息
        String jdDeptId;
        //填充街道信息
        jdDeptId = putJd(data, departmentName);
        String sqDeptId = null;
        // 填充社区信息
        sqDeptId = putSq(data, longitude, latitudes, jdDeptId, sqDeptId);
        String wgDeptId = null;
        // 填充网格信息
        wgDeptId = putWg(data, longitude, latitudes, sqDeptId, wgDeptId);

        // 填充创建人信息
        if (StringUtils.isNotBlank(wgDeptId)) {
            List<UserModel> usersByDeptId = organizationFacade.getUsersByDeptId(wgDeptId);
            if (CollectionUtils.isNotEmpty(usersByDeptId) && Objects.nonNull(usersByDeptId.get(0))) {
                data.put(DefaultPropertyType.CREATER.getCode(), usersByDeptId.get(0).getId());
                data.put(DefaultPropertyType.CREATED_DEPT_ID.getCode(), usersByDeptId.get(0).getDepartmentId());
            }
        }
        // 事件图片
        data.remove("alarmPictureUrl");
        data.remove("videos");
        putImages(data, itData);
        return new BizObjectModel(SCHMEA_CODE, data, Boolean.FALSE);

    }

    private String putJd(Map<String, Object> data, String departmentName) {
        String departmentId = null;
        if (StringUtils.isNotBlank(departmentName)) {
            List<Department> departments = departmentService.getDepartmentsByName(departmentName, Boolean.FALSE);
            if (CollectionUtils.isNotEmpty(departments)) {
                departmentId = departments.get(0).getId();
                String deptName = departments.get(0).getName();
                // 所属街道（部门控件）
                data.put("ssjd", departmentId);
            }
        }
        return departmentId;
    }

    private String putWg(Map<String, Object> data, String longitude, String latitudes, String sqDeptId, String wgDeptId) {
        if (StringUtils.isNotBlank(sqDeptId)) {
            List<Map<String, Object>> wgJwd = queryReportSqlController.getJdJwd(sqDeptId);
//            double[] doublesWGS = CoordtransformUtils.GCJ02toWGS84(Double.parseDouble(longitude), Double.parseDouble(latitudes));
            double[] doublesME = CoordtransformUtils.WGS84toMercator(Double.parseDouble(longitude), Double.parseDouble(latitudes));
            Point2D.Double aDouble = new Point2D.Double(doublesME[0], doublesME[1]);
            for (Map<String, Object> map : wgJwd) {
                String jwd = MapUtils.getString(map, "jwd");
                if (StringUtils.isBlank(jwd)) {
                    continue;
                }
                List<Point2D.Double> doubles = PolygonUtil.parsePointDoubles(jwd);
                boolean inPolygon = PolygonUtil.isInPolygon(aDouble, doubles);
                if (inPolygon) {
                    // 网格部门id
                    wgDeptId = MapUtils.getString(map, "id");
                    data.put("sswg", wgDeptId);
                    break;
                }
            }
        }
        return wgDeptId;
    }

    private String putSq(Map<String, Object> data, String longitude, String latitudes, String jdDeptId, String sqDeptId) {
        if (StringUtils.isNotBlank(jdDeptId)) {
            List<Map<String, Object>> sqJwd = queryReportSqlController.getJdJwd(jdDeptId);
//            double[] doublesWGS = CoordtransformUtils.GCJ02toWGS84(Double.parseDouble(longitude), Double.parseDouble(latitudes));
            double[] doublesME = CoordtransformUtils.WGS84toMercator(Double.parseDouble(longitude), Double.parseDouble(latitudes));
            Point2D.Double aDouble = new Point2D.Double(doublesME[0], doublesME[1]);
            for (Map<String, Object> map : sqJwd) {
                String jwd = MapUtils.getString(map, "jwd");
                if (StringUtils.isBlank(jwd)) {
                    continue;
                }
                List<Point2D.Double> doubles = PolygonUtil.parsePointDoubles(jwd);
                boolean inPolygon = PolygonUtil.isInPolygon(aDouble, doubles);
                if (inPolygon) {
                    // 社区部门id
                    sqDeptId = MapUtils.getString(map, "id");
                    data.put("sssq", sqDeptId);
                    break;
                }
            }
        }
        return sqDeptId;
    }

    private void putImages(Map<String, Object> data, ItData itData) {
        String alarmPictureUrl = itData.getAlarmPictureUrl();
        if (StringUtils.isNotBlank(alarmPictureUrl)) {
            List<Map<String, Object>> attachmentModels = new ArrayList<>();
                try {
                    String baseString = convertImageUrlToBase64(alarmPictureUrl);
                    byte[] imageBytes = Base64.getDecoder().decode((String) baseString);
                    UUID uuid = UUID.randomUUID();
                    String fileName = uuid + ".jpg";
                    MultipartFile file = new MockMultipartFile(fileName, fileName, "jpg", imageBytes);
                    InputStream inputStream = file.getInputStream();
                    OpenEngine openEngine = OpenEngineFactory.getOpenEngine();
                    String refId = openEngine.uploadFile(fileName, inputStream);
                    AttachmentModel attachmentModel = new AttachmentModel();
//                attachmentModel.setFileSize((file.getSize()));
                    attachmentModel.setRefId(refId);
                    attachmentModel.setName(refId);
                    attachmentModel.setSchemaCode(SCHMEA_CODE);
                    attachmentModel.setFileExtension(".jpg");
                    attachmentModel.setMimeType("image/jpg");
                    attachmentModels.add(BeanUtil.beanToMap(attachmentModel));
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            if (CollectionUtils.isNotEmpty(attachmentModels)) {
                data.put("alarmPictureUrl", attachmentModels);
            }
        }
    }

    private String convertImageUrlToBase64(String imageUrl) throws IOException {
        URL url = new URL(imageUrl);
        URLConnection urlConnection = url.openConnection();
        urlConnection.setRequestProperty("User-Agent", "Mozilla/5.0");

        try (InputStream in = urlConnection.getInputStream();
             ByteArrayOutputStream out = new ByteArrayOutputStream()) {

            byte[] buf = new byte[1024];
            int n;
            while ((n = in.read(buf)) != -1) {
                out.write(buf, 0, n);
            }

            byte[] imageBytes = out.toByteArray();
            return Base64.getEncoder().encodeToString(imageBytes);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


}
